<?php
/* SVN FILE: $Id: app_controller.php 25 2008-08-29 21:58:28Z namaless $ */
/**
 * File contentente le funzionalità per la gestione della versione.
 *
 * @author			Pereira Pulido Nuno Ricardo | Namaless | namaless@gmail.com
 * @author			Zohaib Sibte Hassan
 * @copyright		Copyright 1981-2008, Namaless.
 * @copyright		Copyright (c) 2008, Zohaib Sibte Hassan.
 * @link			http://www.namaless.com Namaless Blog
 * @version			1.0
 * @version			0.9.1
 * @version			$Revision: 25 $
 * @modifiedby		$LastChangedBy: namaless $
 * @lastmodified	$Date: 2008-08-29 23:58:28 +0200 (ven, 29 ago 2008) $
 * @license			http://www.opensource.org/licenses/gpl-license.php GNU Public License
 */

/**
 * Classe astratta Active Record.
 */
abstract class Active_Record
{
	var $select 	= array();
	var $from 		= '';
	var $joins 		= array();
	var $where 		= '';
	var $group 		= array();
	var $order 		= array();
	var $limit		= array();
	var $having 	= '';
	var $tblData 	= array();

	// --------------------------------------------------------------------

	function &select()
	{
		$args = func_get_args();
		foreach($args as $arg)
		{
			if(is_array($arg))
				call_user_func_array(array(&$this,'select'),$arg);
			else
				$this->select[]=$arg;
		}

		return $this;
	}

	// --------------------------------------------------------------------

	function &from($table)
	{
		$this->from = $table;
		return $this;
	}

	// --------------------------------------------------------------------

	function &having($str,$value=FALSE,$operator='AND')
	{
		if(is_array($str))
		{
			$operator = ((is_bool($value))?'AND':$value);
			foreach($str as $f=>$v)
				$this->having($f,$v,$operator);
			return $this;
		}
		else
		{
			$replaced = strpos($str,'?');
			if(is_array($value))
			{
				if($replaced !== FALSE)
					$str = str_replace('?',implode(',',$this->_quote($value)),$str);
				else
					$str = $str.' IN ('.implode(',',$this->_quote($value)).') ';
			}
			else if($value === NULL)
			{
				if($replaced !== FALSE)
					$str = str_replace('?','NULL',$str);
				else
					$str = $str.' IS NULL ';
			}
			else if($value !== FALSE)
			{
				if($replaced !== FALSE)
					$str = str_replace('?',$this->_quote($value),$str);
				else
					$str = $str.' = '.$this->_quote($value).' ';
			}
		}

		if(strlen($this->having)==0)
			$this->having=$str;
		else
			$this->having.=$operator.' '.$str;

		return $this;
	}

	// --------------------------------------------------------------------

	function &where($str,$value=FALSE,$operator='AND')
	{
		if(is_array($str))
		{
			$operator = (($value===FALSE)?'AND':$value);
			foreach($str as $f=>$v)
				$this->where($f,$v,$operator);
			return $this;
		}
		else if($value!==FALSE)
		{
			$str = trim($str);
			if(is_array($value))
			{
				if(strpos($str,':')!==FALSE)
					$str = $this->_parseConditionWithArray($str,$value);
				else if($this->_hasArrayOperator($str))
					$str = $str. ' ('.implode(',',$this->_quote($value)).') ';
				else
					$str = $str.' IN ('.implode(',',$this->_quote($value)).') ';

			}
			else if($value===NULL)
				$str = $str.' IS NULL';
			else if($this->_hasOperator($str))
				$str = $str . $this->_quote($value);
			else
				$str = $str .' = '. $this->_quote($value);
		}

		if(strlen($this->where)==0)
			$this->where=$str;
		else
			$this->where.=' '.$operator.' '.$str;

		return $this;
	}

	// --------------------------------------------------------------------

	function _hasArrayOperator($str){
		$str = strtoupper($str);
		return strpos($str,'IN')!==FALSE || strpos($str,'IS')!==FALSE || strpos($str,'NOT')!==FALSE;
	}

	// --------------------------------------------------------------------

	function _hasOperator($str){
		return strpos($str,'=')!==FALSE || strpos($str,'>')!==FALSE || strpos($str,'<')!==FALSE || strpos($str,'!')!==FALSE;
	}

	// --------------------------------------------------------------------

	function _parseConditionWithArray($str,$ar){
		foreach($ar as $vr => $vl){
			$rep = ':'.$vr;
			if(is_array($vl))
				$str = str_replace($rep,'('.implode(',',$this->_quote($vl)).')',$str);
			else if($vl===NULL)
				$str = str_replace($rep,'NULL',$str);
			else
				$str = str_replace($rep,$this->_quote($vl),$str);
		}
		return $str;
	}

	// --------------------------------------------------------------------

	function _deject($val){
		if(is_array($val)){
			foreach($val as $i=>$v)
				$val[$i] = addslashes($v);
		}else{
			$val = addslashes(''.$val);
		}
		return $val;
	}

	// --------------------------------------------------------------------

	function _quote($val)
	{
		if ( is_array($val) )
		{
			foreach ( $val AS $i => $v )
			{
				if($v !== NULL)
				{
					$val[$i] = '\'' . addslashes($v) . '\'';
				}
				else
				{
					$val[$i] = 'NULL';
				}
			}
		}
		else
		{
			if ( $val !== NULL )
			{
				$val = '\'' . addslashes('' . $val) . '\'';
			}
			else
			{
				$val = 'NULL';
			}
		}
		
		return $val;
	}

	// --------------------------------------------------------------------

	function &join($table, $condition, $type = '')
	{
		array_push($this->joins, " $type JOIN $table ON ($condition)");
		return $this;
	}

	// --------------------------------------------------------------------

	function &groupBy()
	{
		$args = func_get_args();

		foreach ( $args AS $arg )
		{
			if ( is_array($arg) )
			{
				call_user_func_array(array(&$this, 'groupBy'), $arg);
			}
			else
			{
				$this->group[] = $arg;
			}
		}

		return $this;
	}

	// --------------------------------------------------------------------

	function &orderBy($p, $type = FALSE)
	{
		if ( is_array($p) )
		{
			foreach ( $p AS $n => $t )
			{
				if ( is_string($n) )
				{
					$this->order[] = $n . ' ' . strtoupper($t);
				}
				else
				{
					$this->order[] = $t . ' DESC ';
				}
			}
		}
		else if ( is_string($p) )
		{
			$type = ( ($type===FALSE) ? 'DESC' : $type );
			$this->order[]= "$p $type";
		}

		return $this;
	}

	// --------------------------------------------------------------------

	function &limit($start, $total)
	{
		// Controllo che siano impostati start e total.
		if ( $start === NULL OR $total === NULL )
		{
			return;
		}

		$this->limit = array($start, $total);
	}

	// --------------------------------------------------------------------

	function _compileSelect()
	{
		$qry  = 'SELECT ';
		
		if ( count($this->select) > 0 )
		{
			$qry .= implode(',', $this->select);
		}
		else
		{
			$qry .= '*';
		}

		$qry .= ' FROM ' . $this->from;
		$qry .= implode('', $this->joins);

		if ( strlen($this->where) > 0 )
		{
			$qry .= ' WHERE ' . $this->where;
		}

		if ( count($this->group) > 0 )
		{
			$qry .= ' GROUP BY ' . implode(',', $this->group);
		}

		if ( strlen($this->having) > 0 )
		{
			$qry .= ' HAVING ' . $this->having;
		}
		

		if ( count($this->order) > 0 )
		{
			$qry .= ' ORDER BY ' . implode(',', $this->order);
		}

		if ( count($this->limit) > 0 )
		{
			$qry .= ' LIMIT ' . implode(',', $this->limit);
		}

		return $qry;
	}

	// --------------------------------------------------------------------

	function reset()
	{
		$this->select = array();
		$this->from = array();
		$this->join = array();
		$this->where = '';
		$this->group = array();
		$this->order = array();
		$this->limit = array();
		$this->tblData = array();
	}

	// --------------------------------------------------------------------

	function &set()
	{
		$args = func_get_args();

		if ( count($args) == 1 AND is_array($args[0]) )
		{
			$this->tblData = array_merge($this->tblData, $args[0]);
		}
		else if ( is_string($args[0]) AND count($args) == 2 )
		{
			$this->tblData[$args[0]] = $args[1];
		}

/*		else if( is_string($args[0]) && count($args)==3 )
			$this->tblData[$args[0]] = str_replace('?',$this->_deject($arg[2]),$args[1]);*/

		return $this;
	}

	// --------------------------------------------------------------------

	function insert_query($table, $fields = NULL)
	{
		if ( is_array($fields) )
		{
			$this->set($fields);
		}

		$datv = array();
		$flds = array();

		foreach ( $this->tblData AS $fld => $val )
		{
			$datv[] = $val;
			$flds[] = $fld;
		}

		$qry  = 'INSERT INTO ' . $table;
		$qry .= '(' . implode(',', $flds) . ')';
		$qry .= ' VALUES ';
		$qry .= '(' . implode(',', $this->_quote($datv)) . ')';

		return $qry;
	}

	// --------------------------------------------------------------------

	function update_query($table, $fields = NULL)
	{
		if ( is_array($fields) )
		{
			$this->set($fields);
		}
		
		$uds = array();
		foreach ( $this->tblData AS $fld => $val )
		{
			$uds[] = $fld . ' = ' . $this->_quote($val);
		}

		$qry  = 'UPDATE ' . $table . ' SET ';
		$qry .= implode(',', $uds);

		if ( strlen($this->where) > 0 )
		{
			$qry .= ' WHERE ' . $this->where;
		}

		return $qry;
	}

	// --------------------------------------------------------------------

	function delete_query($table)
	{
		$qry  = 'DELETE FROM ' . $table;
		if ( strlen($this->where) > 0 )
		{
			$qry .= ' WHERE ' . $this->where;
		}

		return $qry;
	}

	// --------------------------------------------------------------------

	function select_query($fr=FALSE)
	{
		if ( $fr !== FALSE )
		{
			$this->from($fr);
		}
		
		return $this->_compileSelect();
	}
}

?>
